#include "sundry.h"

#include <Windows.h>

#include <QFile>
#include <QDebug>

#include <vector>
#include <string>
#include <fstream>
#include <sstream>

#include <iostream>

EncodingEnum getLocalEncoding()
{
    EncodingEnum encoding = EncodingEnum::UTF8;
    UINT acp = GetACP(); // 返回 Windows 系统的 "ANSI Code Page"
    switch (acp)
    {
    case 936: // GBK
        encoding = EncodingEnum::GB18030;
        break;
    case 54936: // GB18030
        encoding = EncodingEnum::GB18030;
        break;
    case 65001: // UTF-8
        encoding = EncodingEnum::UTF8;
        break;
    default: // 其它默认为UTF-8
        encoding = EncodingEnum::UTF8;
        break;
    }
    return encoding;
}

QString byteArrayToHexSpaced(const QByteArray& data)
{
    QString hex = QString::fromLatin1(data.toHex()).toUpper();
    if (hex.isEmpty())
        return hex;

    QString result;
    for (int i = 0; i < hex.length(); i += 2)
    {
        result += hex.mid(i, 2);
        result += ' ';
    }
    return result;
}

QByteArray hexSpacedToByteArray(const QString& hexStr)
{
    QString cleaned = hexStr.simplified().remove(' '); // 去掉空格
    return QByteArray::fromHex(cleaned.toLatin1());
}

QByteArray getEncodingString(EncodingEnum encoding)
{
    QByteArray result = "UTF-8";
    switch (encoding)
    {
    case EncodingEnum::GB18030:
        result = "GB18030";
        break;
    case EncodingEnum::UTF8:
        result = "UTF-8";
        break;
    default:
        result = "UTF-8";
        break;
    }
    return result;
}

std::vector<std::vector<std::string>> readCSVFile(const std::string& filePath)
{
    std::vector<std::vector<std::string>> data;

    // 1. 打开文件
    std::ifstream file(filePath);
    if (!file.is_open())
    {
        std::cout << "无法打开文件: " << filePath << std::endl;
        return data; // 返回空向量
    }

    std::string line;

    // 2. 逐行读取
    while (std::getline(file, line))
    {
        // 跳过空行
        if (line.empty())
        {
            continue;
        }

        std::vector<std::string> row;
        std::stringstream ss(line);
        std::string cell;

        // 3. 按逗号分割每行
        while (std::getline(ss, cell, ','))
        {
            row.push_back(cell);
        }

        // 4. 添加到数据向量
        data.push_back(row);
    }

    // 5. 关闭文件
    file.close();
    // std::cout << "读取到" << data.size() << "行 " << data[0].size() << "列" << std::endl;

    return data;
}

int findPortInfoIndex(const QSerialPortInfo& targetPort, const QList<QSerialPortInfo>& portList)
{
    if (targetPort.isNull())
    {
        return -1;
    }

    QString targetPortName = targetPort.portName();
    QString targetDescription = targetPort.description();
    QString targetSystemLocation = targetPort.systemLocation();
    // qDebug()<<"targetPort"<<targetPortName<<targetDescription<<targetSystemLocation;

    // qDebug()<<"portList";
    for (int i = 0; i < portList.size(); ++i)
    {
        const QSerialPortInfo& port = portList.at(i);
        // qDebug()<<port.portName()<<port.description()<<port.systemLocation();

        // 使用多个属性进行匹配，提高准确性
        if (port.portName() == targetPortName && port.description() == targetDescription && port.systemLocation() == targetSystemLocation)
        {
            // qDebug()<<"已找到";
            return i;
        }
    }

    // qDebug()<<"未找到";
    return -1;
}

/**
 * @brief 判断一个字符是否为合法的十六进制字符（0-9, A-F, a-f）
 * @param ch 字符
 * @return true 是，false 否
 */
bool isHexChar(QChar ch)
{
    return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
}

// /**
//  * @brief isValidHexSequence
//  * @param theSymbol
//  * @return
//  * @note 这是严格版
//  */
// bool isValidHexSequence(const QString& theSymbol)
// {
//     QString str = theSymbol.trimmed(); // 去除前后空格

//     if (str.isEmpty())
//     {
//         return false;
//     }

//     int byteCount = 0;  // 当前正在处理第几个字节
//     int charInByte = 0; // 当前字节中已读取的字符数（应为0或1或2）

//     for (int i = 0; i < str.length(); ++i)
//     {
//         QChar ch = str[i];

//         if (ch == ' ')
//         {
//             // 遇到空格：检查当前字节是否完整（必须是2个字符）
//             if (charInByte != 2)
//             {
//                 return false; // 空格前不是完整的2位，非法
//             }
//             charInByte = 0; // 重置，准备下一个字节
//             byteCount++;
//         }
//         else
//         {
//             // 是普通字符：必须是十六进制字符
//             if (!isHexChar(ch))
//             {
//                 return false; // 非法字符
//             }
//             charInByte++;
//             if (charInByte > 2)
//             {
//                 return false; // 一个字节超过2个字符，非法
//             }
//         }
//     }

//     // 循环结束后，检查最后一个字节是否完整
//     if (charInByte != 2)
//     {
//         return false; // 最后一个字节不完整
//     }

//     // 至少有一个完整字节
//     return byteCount + (charInByte == 2 ? 1 : 0) > 0;
// }

bool isValidHexSequence(const QString& theString)
{
    // 第一步：提取所有非空格字符
    QString cleaned;
    for (QChar ch : theString)
    {
        if (ch != ' ')
        {
            cleaned += ch;
        }
    }

    // 第二步：检查是否为空
    if (cleaned.isEmpty())
    {
        return false;
    }

    // 第三步：检查每个字符是否都是十六进制字符
    for (QChar ch : cleaned)
    {
        if (!isHexChar(ch))
        {
            return false;
        }
    }

    // 第四步：检查字符总数是否为偶数（每个字节2位）
    return (cleaned.length() % 2) == 0;
}
